#include <stdio.h>
#include <string.h>
#include <rte_launch.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_lcore.h>
#include <rte_debug.h>
#include <rte_mbuf.h>
#include <rte_malloc.h>
#include <rte_timer.h>
#include <rte_arp.h>

// make SRCS=hello_world.c
/*
DPDK 的 lcore 指的是 EAL 线程,本质是基于pthread （ Linux/FreeBSD ）封装实现。Lcore（ EAL pthread ）由
remote_launch函数指定的任务创建并管理。在每个EAL pthread中，有一个TLS（Thread Local Storage）称为_lcore_id。
*/
static int lcore_hello(__rte_unused void *arg) {
    unsigned lcore_id;
    lcore_id = rte_lcore_id();
    printf("hello from core %u\n", lcore_id);
    return 0;
}

static void print_format_str(char * name, char * str){
    printf("%s ----------->  %s \n", name, str);
}


static void print_format_int(char * name, int num){
    printf("%s ----------->  %d \n", name, num);
}

void lcore_id_print(){
    unsigned sock_id = rte_lcore_id();
    print_format_int("rte_lcore_id", sock_id);
    sock_id = rte_get_next_lcore(sock_id, 1, 0);
    print_format_int("rte_get_next_lcore", sock_id);
    sock_id = rte_get_next_lcore(sock_id, 1, 0);
    print_format_int("rte_get_next_lcore", sock_id);
}


int main(int argc, char **argv)
{
    int ret;   
    unsigned int lcore_id;
    ret = rte_eal_init(argc, argv);
    if(ret < 0){
        rte_panic("can not eal init");
    }

    unsigned sys_ports = rte_eth_dev_count_avail();
    print_format_int("rte_eth_dev_count_avail", sys_ports);

    unsigned sock_id = rte_socket_id();
    print_format_int("rte_socket_id", sock_id);

    lcore_id_print();

    print_format_int("rte_sys_gettid", rte_sys_gettid());

    RTE_LCORE_FOREACH_WORKER(lcore_id){
        rte_eal_remote_launch(lcore_hello, NULL, lcore_id);
    }
    lcore_hello(NULL);

    rte_eal_mp_wait_lcore();
    rte_eal_cleanup();
    return ret;
}
